This task is automated for you by the InstallRealCDEFUPP or the AttachRealCDEFUPP routines in the StubCDEFIntf.p file.
The StubCDEF stub works by retrieving the real control defproc from the control's refCon and then calling it. Unfortunately, you lose the ability to use the control refCon for other purposes; this is compensated by the ability of debugging your CDEF at the source level.
Moreover, disposing of the control without disposing of its ctrlDefUPP may cause memory leaks; see below for the solution implemented in the StubCDEFIntf.p file.
Note
----
There are two problems with this approach: the initCntl and dispCntl messages aren't handled by your 'real' control defproc.
The Control Manager sends the initCntl just after it creates a control; unfortunately, at this time the only defproc active is the StubCDEF, which simply doesn't yet know how to respond. This means that all the initialization and data allocation needed by the real defproc couldn't theoretically be done.
In addition, when an application call DisposeControl (or any other Toolbox routine that disposes of some control) the Control Manager sends the dispCntl message to the control defproc: if you dispose of the 'real' defproc before disposing of the control, then the defproc cannot deallocate all the memory it requested at initialization time.
The solutions to these problems are in the StubCDEFIntf.p file.
The InstallRealCDEFUPP loads a control template with GetNewControl, installs the 'real' defproc into the control refCon, then calls it explicitly with the initCntl message, like:
result := CallControlDefProc(GetControlVariant(outControlHdl), outControlHdl, initCntl, 0, ctrlDefUPP);
The AttachRealCDEFUPP performs the same function, but with an already created control.
The RemoveRealCDEFUPP solves the memory leaking problem with the dispCntl message. Before calling DisposeControl (or any other Toolbox routine that disposes of your control) call RemoveRealCDEFUPP to deallocate any storage you may have allocated at initialization and to dispose of the real defproc UPP. This is done by calling explicitly the real defproc with the dispCntl message, like:
result := CallControlDefProc(GetControlVariant(inControlHdl), inControlHdl, dispCntl, 0, ctrlDefUPP);